#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include "led_opr.h"
#include "led_drv.h"
#include "led_resource.h"


static int g_ledpins[100];
static int g_ledcnt = 0;

static int board_demo_led_init(int which) /* 初始化LED，which-哪个LED*/
{
	
	printk("init gpio:group %d, pin %d\n", GROUP(g_ledpins[which]), PIN(g_ledpins[which]));
	switch(GROUP(g_ledpins[which]))
	{
		case 0:
		{
			printk("init pin of group 0 ...\n");
			break;
		}
		case 1:
		{
			printk("init pin of group 1 ...\n");
			break;
		}
		case 2:
		{
			printk("init pin of group 2 ...\n");
			break;
		}
		case 3:
		{
			printk("init pin of group 3 ...\n");
			break;
		}
	}
	return 0;
}

static int board_demo_led_ctl (int which, char status) /* 控制LED，which-哪个LED，status：1-亮，0-灭 */
{

	printk("ctl gpio:group %d, pin %d\n", GROUP(g_ledpins[which]), PIN(g_ledpins[which]));
	switch(GROUP(g_ledpins[which]))
	{
		case 0:
		{
			printk("ctl pin of group 0 ...\n");
			break;
		}
		case 1:
		{
			printk("ctl pin of group 1 ...\n");
			break;
		}
		case 2:
		{
			printk("ctl pin of group 2 ...\n");
			break;
		}
		case 3:
		{
			printk("ctl pin of group 3 ...\n");
			break;
		}
	}
	return 0;
}

static struct led_operations board_demo_led_opr = {
	.init = board_demo_led_init,
	.ctl = board_demo_led_ctl,
};

static int chip_demo_gpio_led_probe(struct platform_device *pdev)
{
	struct device_node *np;
	struct resource *res;
	int err = 0;
	int led_pin;

    np = pdev->dev.of_node;
    if (!np)
        return -1;

    err = of_property_read_u32(np, "pin", &led_pin);

    g_ledpins[g_ledcnt] = led_pin;

    /* device_create*/
    led_class_create_device(g_ledcnt);
    g_ledcnt++;

    return 0;
}

static int chip_demo_gpio_led_remove(struct platform_device *pdev)
{
	int i;
	struct device_node *np;
	int led_pin;
	int err;

    np = pdev->dev.of_node;
    if (!np)
    {
        return -1;
    }

	err = of_property_read_u32(np, "pin", &led_pin);
	
	/*device_destory*/
    for (i = 0; i < g_ledcnt; i++)
    {
        if (g_ledpins[i] == led_pin)
        {
            led_class_destroy_device(i);
            g_ledpins[i] = -1;
            break;
        }
    }

    for (i = 0; i < g_ledcnt; i++) {
        if (g_ledpins[i] != -1)
            break;
    }

    if (i == g_ledcnt )
    {
        g_ledcnt = 0;
    }

	return 0;
}

static const struct of_device_id rk3399_leds[] = {
    { .compatible = "rk3399,leddrv"},
    { },
};

static struct platform_driver chip_demo_gpio_driver = {
	.probe = chip_demo_gpio_led_probe,
	.remove = chip_demo_gpio_led_remove,
	.driver = {
		.name = "rk3399_led",
		.of_match_table = rk3399_leds,
	},
};

static int chip_demo_gpio_drv_init(void)
{
    int err;

    err = platform_driver_register(&chip_demo_gpio_driver);
	register_led_operations(&board_demo_led_opr);

    return 0;
}

static void chip_demo_gpio_drv_exit(void)
{
    platform_driver_unregister(&chip_demo_gpio_driver);
}

module_init(chip_demo_gpio_drv_init);
module_exit(chip_demo_gpio_drv_exit);
MODULE_LICENSE("GPL");